//
// Copyright (C) [2024] Xingyun Integrated Circuit, Inc.
//
// GreenCode was a private technology asset of Xingyun Integrated Circuit， Inc （Confidential）
//  Author: Shawn.Tan
//  Date : 2025.10.28
//
//  History : Initial Version 2025.10.28
//

//
#ifndef Green_PteAttributeGPGPU_H
#define Green_PteAttributeGPGPU_H

#include "Object.h"
#include "PteAttribute.h"

namespace Green {

  /*!
    \class AddressPteAttributeGPGPU
    \brief pte attribute to manage address and corresponding fault behavior
  */
  class AddressPteAttributeGPGPU : public AddressPteAttribute
  {
  public:
    Object* Clone() const override { return new AddressPteAttributeGPGPU(*this); } //!< Return a cloned ValidPteAttributeGPGPU object of the same type and same contents of the object.
    const char* Type() const override { return "AddressPteAttributeGPGPU"; } //!< Return the type of the ValidPteAttributeGPGPU object.

    AddressPteAttributeGPGPU() : AddressPteAttribute() { } //!< Constructor.
    ~AddressPteAttributeGPGPU() { } //!< Destructor.

    void Generate(const GenPageRequest& rPagingReq, const VmAddressSpace& rVmas, PageTableEntry& rPte) override; //!< Generate AddressPteAttributeGPGPU details.
  protected:
    AddressPteAttributeGPGPU(const AddressPteAttributeGPGPU& rOther) : AddressPteAttribute(rOther) { } //!< Copy constructor.
  };

  /*!
    \class DAPteAttributeGPGPU
    \brief pte attribute to manage the DA bits and corresponding fault behavior
  */
  class DAPteAttributeGPGPU : public ExceptionConstraintPteAttribute
  {
  public:
    Object* Clone() const override { return new DAPteAttributeGPGPU(*this); } //!< overridden method to clone XPteAttribute object
    const char* Type() const override { return "DAPteAttributeGPGPU"; } //!< overridden method to return XPteAttribute as object type
    DAPteAttributeGPGPU() : ExceptionConstraintPteAttribute() { } //!< Constructor
    ~DAPteAttributeGPGPU() { } //!< Destructor

  protected:
    DAPteAttributeGPGPU(const DAPteAttributeGPGPU& rOther) : ExceptionConstraintPteAttribute(rOther) { } //!< Copy Constructor
    EPagingExceptionType GetExceptionType(const GenPageRequest& rPagingReq) const override; //!< Get exception type.
    void ExceptionTriggeringConstraint(const GenPageRequest& rPagingReq, const VmAddressSpace& rVmas, cuint32 pteLevel, ConstraintSet& rTriggerConstr) const override; //!< Return constraint that will trigger the exception.
    void ExceptionPreventingConstraint(const GenPageRequest& rPagingReq, const VmAddressSpace& rVmas, ConstraintSet& rPreventConstr) const override; //!< Return constraint that will prevent the exception.
    void SetPteGenAttribute(const GenPageRequest& rPagingReq, PageTableEntry& rPte) const override; //!< Hook to set PageGenAttribute onto the PageTableEntry object.
    bool EvaluateArchFaultChoice(const VmAddressSpace& rVmas, PageTableEntry& rPte, bool& rHardFaultChoice) const override; //!< Hook to evaluate whether to apply individual field based faults.
  };

  /*!
    \class GPteAttributeGPGPU
    \brief pte attribute to manage the global bit
  */
  class GPteAttributeGPGPU : public ConstraintPteAttribute
  {
  public:
    Object* Clone() const override { return new GPteAttributeGPGPU(*this); } //!< overridden method to clone WPteAttribute object
    const char* Type() const override { return "GPteAttributeGPGPU"; } //!< overridden method to return WPteAttribute as object type
    GPteAttributeGPGPU() : ConstraintPteAttribute() { } //!< Constructor
    ~GPteAttributeGPGPU() { } //!< Destructor

  protected:
    GPteAttributeGPGPU(const GPteAttributeGPGPU& rOther) : ConstraintPteAttribute(rOther) { } //!< Copy Constructor
    bool GetValueConstraint(const GenPageRequest& rPagingReq, const VmAddressSpace& rVmas, PageTableEntry& rPte, ConstraintSet& rValueConstr) const override; //!< Get value constraint for G pte attribute
  };

  /*!
    \class UPteAttributeGPGPU
    \brief pte attribute to manage the 'U' (User access) bit and corresponding fault behavior
  */
  class UPteAttributeGPGPU : public ExceptionConstraintPteAttribute
  {
  public:
    Object* Clone() const override { return new UPteAttributeGPGPU(*this); } //!< overridden method to clone UPteAttribute object
    const char* Type() const override { return "UPteAttributeGPGPU"; } //!< overridden method to return UPteAttribute as object type
    UPteAttributeGPGPU() : ExceptionConstraintPteAttribute() { } //!< Constructor
    ~UPteAttributeGPGPU() { } //!< Destructor

  protected:
    UPteAttributeGPGPU(const UPteAttributeGPGPU& rOther) : ExceptionConstraintPteAttribute(rOther) { } //!< Copy Constructor
    EPagingExceptionType GetExceptionType(const GenPageRequest& rPagingReq) const override; //!< Get exception type.
    void ExceptionTriggeringConstraint(const GenPageRequest& rPagingReq, const VmAddressSpace& rVmas, cuint32 pteLevel, ConstraintSet& rTriggerConstr) const override; //!< Return constraint that will trigger the exception.
    void ExceptionPreventingConstraint(const GenPageRequest& rPagingReq, const VmAddressSpace& rVmas, ConstraintSet& rPreventConstr) const override; //!< Return constraint that will prevent the exception.
    void SetPteGenAttribute(const GenPageRequest& rPagingReq, PageTableEntry& rPte) const override; //!< Hook to set PageGenAttribute onto the PageTableEntry object.
    bool EvaluateArchFaultChoice(const VmAddressSpace& rVmas, PageTableEntry& rPte, bool& rHardFaultChoice) const override; //!< Hook to evaluate whether to apply individual field based faults.
  };

  /*!
    \class XPteAttributeGPGPU
    \brief pte attribute to manage the 'X' (Executable) bit and corresponding fault behavior
  */
  class XPteAttributeGPGPU : public ExceptionConstraintPteAttribute
  {
  public:
    Object* Clone() const override { return new XPteAttributeGPGPU(*this); } //!< overridden method to clone XPteAttribute object
    const char* Type() const override { return "XPteAttributeGPGPU"; } //!< overridden method to return XPteAttribute as object type
    XPteAttributeGPGPU() : ExceptionConstraintPteAttribute() { } //!< Constructor
    ~XPteAttributeGPGPU() { } //!< Destructor

  protected:
    XPteAttributeGPGPU(const XPteAttributeGPGPU& rOther) : ExceptionConstraintPteAttribute(rOther) { } //!< Copy Constructor
    EPagingExceptionType GetExceptionType(const GenPageRequest& rPagingReq) const override; //!< Get exception type.
    void ExceptionTriggeringConstraint(const GenPageRequest& rPagingReq, const VmAddressSpace& rVmas, cuint32 pteLevel, ConstraintSet& rTriggerConstr) const override; //!< Return constraint that will trigger the exception.
    void ExceptionPreventingConstraint(const GenPageRequest& rPagingReq, const VmAddressSpace& rVmas, ConstraintSet& rPreventConstr) const override; //!< Return constraint that will prevent the exception.
    void SetPteGenAttribute(const GenPageRequest& rPagingReq, PageTableEntry& rPte) const override; //!< Hook to set PageGenAttribute onto the PageTableEntry object.
    bool EvaluateArchFaultChoice(const VmAddressSpace& rVmas, PageTableEntry& rPte, bool& rHardFaultChoice) const override; //!< Hook to evaluate whether to apply individual field based faults.
  };

  /*!
    \class WRPteAttributeGPGPU
    \brief pte attribute to manage the 'WR' (Writeable/Readable) bits and corresponding fault behavior
  */
  class WRPteAttributeGPGPU : public ExceptionConstraintPteAttribute
  {
  public:
    Object* Clone() const override { return new WRPteAttributeGPGPU(*this); } //!< overridden method to clone WPteAttribute object
    const char* Type() const override { return "WRPteAttributeGPGPU"; } //!< overridden method to return WPteAttribute as object type
    WRPteAttributeGPGPU() : ExceptionConstraintPteAttribute() { } //!< Constructor
    ~WRPteAttributeGPGPU() { } //!< Destructor

  protected:
    WRPteAttributeGPGPU(const WRPteAttributeGPGPU& rOther) : ExceptionConstraintPteAttribute(rOther) { } //!< Copy Constructor
    EPagingExceptionType GetExceptionType(const GenPageRequest& rPagingReq) const override; //!< Get exception type.
    void ExceptionTriggeringConstraint(const GenPageRequest& rPagingReq, const VmAddressSpace& rVmas, cuint32 pteLevel, ConstraintSet& rTriggerConstr) const override; //!< Return constraint that will trigger the exception.
    void ExceptionPreventingConstraint(const GenPageRequest& rPagingReq, const VmAddressSpace& rVmas, ConstraintSet& rPreventConstr) const override; //!< Return constraint that will prevent the exception.
    void SetPteGenAttribute(const GenPageRequest& rPagingReq, PageTableEntry& rPte) const override; //!< Hook to set PageGenAttribute onto the PageTableEntry object.
    bool EvaluateArchFaultChoice(const VmAddressSpace& rVmas, PageTableEntry& rPte, bool& rHardFaultChoice) const override; //!< Hook to evaluate whether to apply individual field based faults.
  private:
    void AdjustDefaultConstraint(cuint32 pteLevel, ConstraintSet& rValueConstr) const override; //!< Adjust default constraint for special cases.
  };

  /*!
    \class VPteAttributeGPGPU
    \brief pte attribute to manage the valid bit and corresponding fault behavior
  */
  class VPteAttributeGPGPU : public ExceptionConstraintPteAttribute
  {
  public:
    Object* Clone() const override { return new VPteAttributeGPGPU(*this); } //!< overridden method to clone VPteAttribute object
    const char* Type() const override { return "VPteAttributeGPGPU"; } //!< overridden method to return VPteAttribute as object type
    VPteAttributeGPGPU() : ExceptionConstraintPteAttribute() { } //!< Constructor
    ~VPteAttributeGPGPU() { } //!< Destructor

  protected:
    VPteAttributeGPGPU(const VPteAttributeGPGPU& rOther) : ExceptionConstraintPteAttribute(rOther) { } //!< Copy Constructor
    EPagingExceptionType GetExceptionType(const GenPageRequest& rPagingReq) const override; //!< Get exception type.
    void ExceptionTriggeringConstraint(const GenPageRequest& rPagingReq, const VmAddressSpace& rVmas, cuint32 pteLevel, ConstraintSet& rTriggerConstr) const override; //!< Return constraint that will trigger the exception.
    void ExceptionPreventingConstraint(const GenPageRequest& rPagingReq, const VmAddressSpace& rVmas, ConstraintSet& rPreventConstr) const override; //!< Return constraint that will prevent the exception.
    void SetPteGenAttribute(const GenPageRequest& rPagingReq, PageTableEntry& rPte) const override; //!< Hook to set PageGenAttribute onto the PageTableEntry object.
    bool EvaluateArchFaultChoice(const VmAddressSpace& rVmas, PageTableEntry& rPte, bool& rHardFaultChoice) const override; //!< Hook to evaluate whether to apply individual field based faults.
  };

}

#endif //Green_PteAttributeGPGPU_H
